/*
 * Copyright 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.yangfei.SportAssistant;

import com.yangfei.SportAssistant.R;
import com.yangfei.SportAssistant.content.TracksColumns;
import com.yangfei.SportAssistant.fragments.DeleteAllTrackDialogFragment;
import com.yangfei.SportAssistant.io.file.TrackWriterFactory.TrackFileFormat;
import com.yangfei.SportAssistant.util.ApiAdapterFactory;
import com.yangfei.SportAssistant.util.Constants;
import com.yangfei.SportAssistant.util.PreferencesUtils;
import com.yangfei.SportAssistant.util.StringUtils;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.support.v4.widget.ResourceCursorAdapter;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;

public class TrackListActivity extends ListActivity
{

	private static final String TAG = TrackListActivity.class.getSimpleName();

	private static final String[] PROJECTION = new String[]
	{
			TracksColumns._ID, TracksColumns.NAME, TracksColumns.CATEGORY, TracksColumns.TOTALTIME,
			TracksColumns.TOTALDISTANCE, TracksColumns.STARTTIME, TracksColumns.DESCRIPTION
	};


	/*
	 * Note that sharedPreferenceChangeListenr cannot be an anonymous inner class.
	 * Anonymous inner class will get garbage collected.
	 */
	private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener()
	{
		@Override
		public void onSharedPreferenceChanged(SharedPreferences preferences, String key)
		{
			// Note that key can be null
			if (getString(R.string.metric_units_key).equals(key))
			{
				metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
			}
			adapter.notifyDataSetChanged();
		}
	};

	// Callback when an item is selected in the contextual action mode
	private ContextualActionModeCallback contextualActionModeCallback = new ContextualActionModeCallback()
	{
		@Override
		public boolean onClick(int itemId, long id)
		{
			return handleContextItem(itemId, id);
		}
	};

	private boolean metricUnits;
	private long recordingTrackId;
	private ListView listView;
	private ResourceCursorAdapter adapter;

	private MenuItem recordTrack;
	private MenuItem stopRecording;
	private MenuItem search;
	private MenuItem importAll;
	private MenuItem exportAll;
	private MenuItem deleteAll;
	
	private Cursor tracksCursor;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.track_list);

		SharedPreferences sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
		sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
		metricUnits = sharedPreferences.getBoolean(getString(R.string.metric_units_key), true);
		recordingTrackId = PreferencesUtils.getRecordingTrackId(this);

		listView = getListView();
		listView.setEmptyView(findViewById(R.id.track_list_empty));
		listView.setOnItemClickListener(new OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id)
			{
				startTrackDetailActivity(id);
			}
		});
		
		tracksCursor = getContentResolver().query(TracksColumns.CONTENT_URI, PROJECTION, null, null, TracksColumns._ID+" DESC");
		startManagingCursor(tracksCursor);
		
		adapter = new ResourceCursorAdapter(this, R.layout.track_list_item, tracksCursor)
		{
			@Override
			public void bindView(View view, Context context, Cursor cursor)
			{
				int idIndex = cursor.getColumnIndex(TracksColumns._ID);
				int nameIndex = cursor.getColumnIndex(TracksColumns.NAME);
				int categoryIndex = cursor.getColumnIndex(TracksColumns.CATEGORY);
				int timeIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALTIME);
				int distanceIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE);
				int startIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
				int descriptionIndex = cursor.getColumnIndex(TracksColumns.DESCRIPTION);
				
				Log.d(TAG, "ResourceCursorAdapter::bindView: TracksColumns.NAME: " + cursor.getString(nameIndex));

				boolean isRecording = cursor.getLong(idIndex) == recordingTrackId;

				TextView name = (TextView) view.findViewById(R.id.track_list_item_name);
				name.setText(cursor.getString(nameIndex));
				name.setCompoundDrawablesWithIntrinsicBounds(isRecording ? R.drawable.menu_record_track : R.drawable.track, 0, 0, 0);

				TextView category = (TextView) view.findViewById(R.id.track_list_item_category);
				category.setText(cursor.getString(categoryIndex));

				TextView time = (TextView) view.findViewById(R.id.track_list_item_time);
				time.setText(StringUtils.formatElapsedTime(cursor.getLong(timeIndex)));
				time.setVisibility(isRecording ? View.GONE : View.VISIBLE);

				TextView distance = (TextView) view.findViewById(R.id.track_list_item_distance);
				distance.setText(StringUtils.formatDistance(TrackListActivity.this, cursor.getDouble(distanceIndex), metricUnits));
				distance.setVisibility(isRecording ? View.GONE : View.VISIBLE);

				TextView start = (TextView) view.findViewById(R.id.track_list_item_start);
				start.setText(StringUtils.formatDateTime(TrackListActivity.this, cursor.getLong(startIndex)));
				start.setVisibility(start.getText().equals(name.getText()) ? View.GONE : View.VISIBLE);

				TextView description = (TextView) view.findViewById(R.id.track_list_item_description);
				description.setText(cursor.getString(descriptionIndex));
				description.setVisibility(description.getText().length() == 0 ? View.GONE : View.VISIBLE);
			}
		};
		setListAdapter(adapter);
		ApiAdapterFactory.getApiAdapter().configureListViewContextualMenu(this, listView, R.menu.track_list_context_menu, R.id.track_list_item_name, contextualActionModeCallback);

	}
	
	@Override
	protected void onResume()
	{
		super.onResume();
	}

	@Override
	protected void onDestroy()
	{
		super.onDestroy();
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		return false;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		getMenuInflater().inflate(R.menu.track_list, menu);
		String fileTypes[] = getResources().getStringArray(R.array.file_types);
		menu.findItem(R.id.track_list_export_gpx).setTitle(getString(R.string.menu_export_all_format, fileTypes[0]));
		menu.findItem(R.id.track_list_export_kml).setTitle(getString(R.string.menu_export_all_format, fileTypes[1]));
		menu.findItem(R.id.track_list_export_csv).setTitle(getString(R.string.menu_export_all_format, fileTypes[2]));
		menu.findItem(R.id.track_list_export_tcx).setTitle(getString(R.string.menu_export_all_format, fileTypes[3]));

		search = menu.findItem(R.id.track_list_search);
		importAll = menu.findItem(R.id.track_list_import_all);
		exportAll = menu.findItem(R.id.track_list_export_all);
		deleteAll = menu.findItem(R.id.track_list_delete_all);

		ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, search);
		updateMenu();
		return true;
	}

	/**
	 * Updates the menu based on whether My Tracks is recording or not.
	 */
	private void updateMenu()
	{
		boolean isRecording = ((SportAssistantApplication) getApplication()).isRecording();
		updateMenuItems(isRecording);
	}

	/**
	 * Updates the menu items.
	 * 
	 * @param isRecording
	 *          true if recording
	 */
	private void updateMenuItems(boolean isRecording)
	{
		if (recordTrack != null)
		{
			recordTrack.setVisible(!isRecording);
		}
		if (stopRecording != null)
		{
			stopRecording.setVisible(isRecording);
		}
		if (importAll != null)
		{
			importAll.setVisible(!isRecording);
		}
		if (exportAll != null)
		{
			exportAll.setVisible(!isRecording);
		}
		if (deleteAll != null)
		{
			deleteAll.setVisible(!isRecording);
		}
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
			case R.id.track_list_search:
				return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this);
			case R.id.track_list_import_all:
				startActivity(new Intent(this, ImportActivity.class).putExtra(ImportActivity.EXTRA_IMPORT_ALL, true));
				return true;
			case R.id.track_list_export_gpx:
				startActivity(new Intent(this, ExportActivity.class).putExtra(ExportActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.GPX));
				return true;
			case R.id.track_list_export_kml:
				startActivity(new Intent(this, ExportActivity.class).putExtra(ExportActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.KML));
				return true;
			case R.id.track_list_export_csv:
				startActivity(new Intent(this, ExportActivity.class).putExtra(ExportActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.CSV));
				return true;
			case R.id.track_list_export_tcx:
				startActivity(new Intent(this, ExportActivity.class).putExtra(ExportActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.TCX));
				return true;
			case R.id.track_list_delete_all:
				//new DeleteAllTrackDialogFragment().show(getSupportFragmentManager(), DeleteAllTrackDialogFragment.DELETE_ALL_TRACK_DIALOG_TAG);
				//DeleteAllTrackDialogFragment aboutDialog = new DeleteAllTrackDialogFragment(this);
				Handler h = new DeleteAllTrackDialogFragment(this, null);
				h.handleMessage(null);
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
	{
		super.onCreateContextMenu(menu, v, menuInfo);
		getMenuInflater().inflate(R.menu.track_list_context_menu, menu);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item)
	{
		if (handleContextItem(item.getItemId(), ((AdapterContextMenuInfo) item.getMenuInfo()).id))
		{
			return true;
		}
		return super.onContextItemSelected(item);
	}

	/**
	 * Handles a context item selection.
	 * 
	 * @param itemId
	 *          the menu item id
	 * @param trackId
	 *          the track id
	 * @return true if handled.
	 */
	private boolean handleContextItem(int itemId, long trackId)
	{
		switch (itemId)
		{
			case R.id.track_list_context_menu_edit:
				startActivity(new Intent(this, TrackEditActivity.class).putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId));
				return true;
			case R.id.track_list_context_menu_delete:
				MainTabActivity.deleteTrack(trackId);
				return true;
			default:
				return false;
		}
	}

	/**
	 * Starts {@link MainTabActivity}.
	 * 
	 * @param trackId
	 *          the track id.
	 */
	private void startTrackDetailActivity(long trackId)
	{
		Intent intent = new Intent(TrackListActivity.this, MainTabActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
				| Intent.FLAG_ACTIVITY_NEW_TASK).putExtra(MainTabActivity.EXTRA_TRACK_ID, trackId);
		//startActivity(intent);
		MainTabActivity mainActivity = (MainTabActivity)getParent();
		mainActivity.onNewIntent(intent);
		mainActivity.switchToTab(Constants.TAB_ITEM_MAP);
	}


	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event)
	{
		if (keyCode == KeyEvent.KEYCODE_SEARCH)
		{
			if (ApiAdapterFactory.getApiAdapter().handleSearchKey(search))
			{
				return true;
			}
		}
		return super.onKeyUp(keyCode, event);
	}
	
	//�޸Ĳ�ˢ�µ�bug
	public void resetList()
	{
		tracksCursor = getContentResolver().query(TracksColumns.CONTENT_URI, PROJECTION, null, null, TracksColumns._ID+" DESC");
		adapter.changeCursor(tracksCursor);
	}
}
